package com.google.code.krillion.firehose.server;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.MessageFormat;
import java.util.ResourceBundle;
import java.util.logging.Logger;
import java.util.regex.Pattern;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.google.appengine.api.labs.taskqueue.Queue;
import com.google.appengine.api.labs.taskqueue.QueueFactory;
import static com.google.appengine.api.labs.taskqueue.TaskOptions.Builder.url;

import twitter4j.TwitterException;
import twitter4j.http.HttpClient;
import twitter4j.http.HttpResponse;

public class ProductWorkerServlet implements Servlet {
    private static Logger log = Logger.getLogger(ProductWorkerServlet.class.getName());
	private static ServletConfig config;
	private static String apiCall;
	private static final Pattern NON_WORD_CHAR_PATTERN = Pattern.compile("\\W"); // a non-word character
	
	@Override
	public void destroy() {
		config = null;
		apiCall = null;
	}

	@Override
	public ServletConfig getServletConfig() {
		return config;
	}

	@Override
	public String getServletInfo() {
		return null;
	}

	@Override
	public void init(ServletConfig sc) throws ServletException {
		config = sc;
		ResourceBundle bundle = ResourceBundle.getBundle("com.google.code.krillion.firehose.server.krillion");
		apiCall = (String) bundle.getObject("krillion.api.call.offers");
	}

	@Override
	public void service(ServletRequest req, ServletResponse resp)
	throws ServletException, IOException {
		String zip = req.getParameter("zip");
		String category = req.getParameter("category");
		log.info("zip:" + zip + ", category:" + category);
		resp.setContentType("text/plain");
		PrintWriter writer = resp.getWriter();
        writer.println("zip:" + zip + ", category:" + category);
		try {
			Object[] args = {zip, category};
			final String url = MessageFormat.format(apiCall, args);
			HttpClient client = new HttpClient();
			HttpResponse response = client.get(url);
//			final String responseStr = response.asString();
//			log.info("responseAsString: " + responseStr);
//			writer.println(responseStr);
			Document dom = response.asDocument();
			NodeList brandList = dom.getElementsByTagName("brand");
			NodeList skuList = dom.getElementsByTagName("sku");
			if (  brandList.getLength() > 0
			   &&   skuList.getLength() > 0
			   && brandList.getLength() == skuList.getLength()) {
				for (int i=0; i < brandList.getLength(); i++) {
					final Node brandNode = brandList.item(i);
					final Node skuNode = skuList.item(i);
					if (  brandNode != null
					   &&   skuNode != null ) {
						final String brand  = brandNode.getTextContent().replace(' ','+');
						final String sku  = NON_WORD_CHAR_PATTERN.matcher(skuNode.getTextContent()).replaceAll("").replaceAll("_", "");
				        Queue queue = QueueFactory.getQueue("availability");
				        queue.add(url("/availability").param("zip", zip).param("brand", brand).param("sku", sku));
				        writer.println("added zip/" + zip + " brand/" + brand+ " sku/" + sku + " combination to availability task queue \n");
					} else {
						log.warning("extracting product brand/sku DOM nodes failed");
						writer.println("extracting product brand/sku DOM nodes failed");
					}
				}
			} else {
				log.warning("extracting product brand/sku NodeLists from Krillion response failed");
				writer.println("extracting product brand/sku NodeLists from Krillion response failed");
			}
			
		} catch (TwitterException e) {
			log.severe("TwitterException processing products queue task: " + e.getMessage());
			writer.println("TwitterException processing products queue task: " + e.getMessage());
		}
		writer.flush();
		writer.close();
	}
	
}
